const http = require("http");
const fs = require("fs");
const url = require("url");
const querystring = require("querystring");
const ChildProcess = require('child_process');
const process = require('process');

/**
 * 创建 http 服务
 * @param req 请求，输入
 * @param res 响应，输出
 */
const server_0 = http.createServer((req, res) => {
  /**
   * 设置状态码与响应头
   * 中文乱码问题，新建文件时，默认保存的编码是 utf-8，所以在输出时同样需要使用 utf-8
   */
  // res.writeHead(200, { "Content-Type": "text/plain" });
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });

  // 响应数据，可调用多次，返回的数据会被拼接到一起
  res.write("Hello Node.js 《学习》");

  // 结束响应，否则会一直处于等待状态
  res.end();
});

// GET 请求，解析数据
const server_1 = http.createServer((req, res) => {
  /**
   * 使用 Node 自带的 url 和 querystring 模块或自定义方法来解析接受的 GET 请求数据
   * @example const [pathname, query] = req.url.split("?");
   */
  const { pathname, query } = url.parse(req.url);
  console.log(url.parse(req.url));
  // 静态资源
  if (pathname.indexOf('public') !== -1) {
    fs.readFile(pathname, (err, data) => {
      console.log(err, '[-err');
      if (err) {
        res.writeHead(404);
        res.end('404');
      } else {
        res.end(data);
      }
    })
  } else {
    const params = querystring.parse(query);
    res.write(JSON.stringify(params));
    res.end();
  }
});

const server_2 = http.createServer((req, res) => {
  /**
   * POST 请求，发送数据是分段的
   * @var data 如果是文件则不能用字符串接受
   */
  let str = "";

  // data 事件，有一段数据到达并会触发，多次
  req.on("data", (data) => {
    str += data;
  });

  // end 事件，数据全部达到时触发，只发生一次
  req.on("end", () => {
    res.write(str);
    res.end();
  });
});

const server_3 = http.createServer((req, res) => {
  const buf = new Buffer(0);
  // 接收请求数据
  req.on('data', (data) => {
    // data 的类型是 Buffer
    buf = Buffer.concat([buf, data]);
  });

  // 接收请求数据结束
  req.on('end', function(){
    console.log(buf.toString('Utf-8'));
    res.write(buf.toString('utf-8'));
    res.end();
    //退出进程
    process.exit();
  });

})
// .listen(listen_port);

//三种方法来保存网络资源文件
function name(params) {
  http.get(options, function(res) {
    //直接使用Buffer的concat来进行连接，合并Buffer之后一次性写入
    var buffer = new Buffer(0);
    //使用字符串来进行读写，这里特别要注意的事情就是编码，特别需要注意的是
    //如果数据是二进制流的话，请一定使用ascii来统一Buffer和String之间的转换
    var buffer2 ='';
    //使用文件句柄来分段写入Buffer，操作时间长，如果文件不大的话
    //最佳的方案是把缓存收集在一起（第一种或第二种），然后进行异步写入到文件
    var fd = fs.openSync('zngril.jpg', 'w');
  
    //如果资源是二进制的，直接使用字符串来收集所有的chunk，然后
    //将chunk写入到文件中是会错误的，因为chunk是Buffer类型，默认转换为String
    //是utf-8的编码，因为是二进制数据，所有有的数据可能不一定能转换成功
    //如果将数据解释失败，则会导致内存缓存块大小不一样而导致文件保存错误.
    //二进制的话，始终用ascii来作为中间编码格式来进行转换，因为ascii是8位的
    //Buffer也是Int8Array，所以按照单个字节是肯定不会出错的。
    //使用方法首先收集Buffer
    //str_buffer += chunk.toString('ascii');
    //fs.writeFileSync(filename, Buffer.from(str_buffer,'ascii'));
    //或者异步写入fs.writeFile(filename, Buffer.from(str_buffer,'asciii'), function(err){});
    //****************************************************************************
    //如果下载资源是文本，有特定的编码格式，则可以直接使用正确的编码来进行解释处理
  
    res.on('data', function(chunk){
        buffer2 += chunk.toString('ascii');
        fs.writeSync(fd, chunk, 0, chunk.length);
        buffer = Buffer.concat([buffer,chunk]);
    });
  
    res.on('end', function(){
        console.log('Data receive complete.');
        fs.closeSync(fd);
        var buf2 = Buffer.from(buffer2,'ascii');
        console.log(Buffer.compare(buffer, buf2));
        console.log('buffer_size ' + buffer.length);
        console.log('buf2_size ' + buf2.length);
  
        fs.writeFileSync('zngril_buffer.jpg', buffer);
        fs.writeFileSync('zngril_buffer2.jpg', buf2);
   });
  });
}

/**
 * 监听端口，不同的端口提供不同的服务
 * 1. 80 Web
 * 2. 110 邮件
 * 3. 3306 数据库
 */
server_0.listen("9000", "0.0.0.0", () => {
  console.log(9000, "服务启动成功~");
   // 使用默认浏览器打开地址
  //  ChildProcess.exec(`start http://${hostname}:${port}/`);
});
server_1.listen("9001", "0.0.0.0", () => {
  console.log(9001, "服务启动成功~");
});
// server_2.listen("8082", "0.0.0.0", () => {
//   console.log(8082, "服务启动成功~");
// });
